;-------------------------------------------------------------------------
;- FILE:      mem_access.a51
;-
;- COPYRIGHT (c) 2010 Atmel Corp.
;-
;- ABSTRACT:  Assembly memory access routines for AT89LP family
;-
;- REVISION HISTORY:
;- 2010/04/30 : created
;-------------------------------------------------------------------------

$INCLUDE(lp51_reg.inc)

;--D----------------------------------------------------------------------
;- Select target device
;-------------------------------------------------------------------------
LP6440 EQU 1
LP828 EQU 2

DEVICE EQU LP6440		; enable for LP6440
;DEVICE EQU LP828		; enable for LP828

;--D----------------------------------------------------------------------
;- Set up memory boundaries
;-------------------------------------------------------------------------
IF (DEVICE = LP6440)
	ERAM_SIZE	EQU	4096
	FDAT_SIZE	EQU	8192
	ERAM_START	EQU	0
	FDAT_START	EQU	ERAM_START+ERAM_SIZE
	XRAM_START	EQU	FDAT_START+FDAT_SIZE
ELSEIF (DEVICE = LP828)
	ERAM_SIZE	EQU	512
	FDAT_SIZE	EQU	1024
	ERAM_START	EQU	0
	FDAT_START	EQU	ERAM_START+ERAM_SIZE
	XRAM_START	EQU	FDAT_START+FDAT_SIZE
ENDIF

;--S----------------------------------------------------------------------
;- Declare segments
;-------------------------------------------------------------------------
	XSEG	AT ERAM_START
MY_EDATA: DS	10

	XSEG	AT FDAT_START
MY_FDATA:	DS	10

	XSEG	AT XRAM_START
MY_XDATA:	DS	10

	CSEG
;--M----------------------------------------------------------------------
;- Example
;-------------------------------------------------------------------------
main:	; after reset EXTRAM, IAP, DMEN, MWEN & SIGEN all zero

	; write to ERAM
	MOV	DPTR, #MY_EDATA
	MOV	A, #55h
	LCALL	write_eram	; write 55h to ERAM

        ; read from ERAM
	MOV	DPTR, #MY_EDATA
	LCALL	read_eram	; ACC <- 55h
	
	; write to FDATA
	MOV	DPTR, #MY_FDATA
	MOV	A, #0AAh
	LCALL	write_fdata	; write AAh to FDATA

        ; read from FDATA
	MOV	DPTR, #MY_FDATA
	LCALL	read_fdata	; ACC <- AAh
	
	; write to XRAM
	MOV	DPTR, #MY_XDATA
	MOV	A, #33h
	LCALL	write_xram	; write 33h to XRAM

        ; read from XRAM
	MOV	DPTR, #MY_XDATA
	LCALL	read_xram	; ACC <- 33h
	
	; write to CODE
	MOV	DPTR, #1234H
	MOV	A, #66h
	LCALL	write_code	; write 66h to ERAM

        ; read from CODE
	MOV	DPTR, #1234H
	LCALL	read_code	; ACC <- 66h

	SJMP	$		; while(1)
	
;--F----------------------------------------------------------------------
;- function: read_eram
;- desciption: read a byte from internal extended RAM
;- parameters: 
;-     DPTR - address in valid ERAM range
;- return value:
;-     ACC - data value
;-------------------------------------------------------------------------

read_eram:
	ANL	AUXR, #~2h	; clear EXTRAM (omit if EXTRAM is never set)
	ANL	MEMCON, #~80h	; clear IAP (omit if IAP is never set)
	MOVX	A, @DPTR
	RET

;--F----------------------------------------------------------------------
;- function: write_eram
;- desciption: write a byte to internal extended RAM
;- parameters: 
;-     DPTR - address in valid ERAM range
;-     ACC  - data to write
;- return value:
;-     none
;-------------------------------------------------------------------------

write_eram:
	ANL	AUXR, #~2h	; clear EXTRAM (omit if EXTRAM is never set)
	ANL	MEMCON, #~80h	; clear IAP (omit if IAP is never set)
	MOVX	@DPTR, A
	RET

;--F----------------------------------------------------------------------
;- function: read_fdata
;- desciption: read a byte from internal flash data
;- parameters: 
;-     DPTR - address in valid FDATA range
;- return value:
;-     ACC - data value
;-------------------------------------------------------------------------

read_fdata:
	ANL	AUXR, #~2h	; clear EXTRAM (omit if EXTRAM is never set)
	ANL	MEMCON, #~80h	; clear IAP (omit if IAP is never set)
	ORL	MEMCON, #8	; set DMEN
	MOVX	A, @DPTR
	ANL	MEMCON, #~8	; clear DMEN
	RET

;--F----------------------------------------------------------------------
;- function: write_fdata
;- desciption: write a byte to internal flash data. Note that the CPU will
;-             idle for several milliseconds while the write completes. Also
;-             a page write of multiple bytes is preferred.
;- parameters: 
;-     DPTR - address in valid FDATA range
;-     ACC  - data to write
;- return value:
;-     none
;-------------------------------------------------------------------------

write_fdata:
	ANL	AUXR, #~2h	; clear EXTRAM (omit if EXTRAM is never set)
	ANL	MEMCON, #~80h	; clear IAP (omit if IAP is never set)
	ANL	MEMCON, #~20h	; clear LDPG (omit if LDPG is never set)
	ORL	MEMCON, #18h	; set DMEN and MWEN
	MOVX	@DPTR, A
	ANL	MEMCON, #~18h	; clear DMEN and MWEN
	RET

;--F----------------------------------------------------------------------
;- function: read_xram
;- desciption: read a byte from external RAM
;- parameters: 
;-     DPTR - address in valid XRAM range
;- return value:
;-     ACC - data value
;-------------------------------------------------------------------------

read_xram:
	ORL	AUXR, #2	; set EXTRAM (omit if address does not
                                ;             overlap ERAM or FDATA)
	ANL	MEMCON, #~80h	; clear IAP (omit if IAP is never set)
	MOVX	A, @DPTR
	ANL	AUXR, #~2	; clear EXTRAM (omit if not set above)
	RET

;--F----------------------------------------------------------------------
;- function: write_xram
;- desciption: write a byte to external RAM
;- parameters: 
;-     DPTR - address in valid XRAM range
;-     ACC  - data to write
;- return value:
;-     none
;-------------------------------------------------------------------------

write_xram:
	ORL	AUXR, #2	; set EXTRAM (omit if address does not
                                ;             overlap ERAM or FDATA)
	ANL	MEMCON, #~80h	; clear IAP (omit if IAP is never set)
	MOVX	@DPTR, A
	ANL	AUXR, #~2	; clear EXTRAM (omit if not set above)
	RET

;--F----------------------------------------------------------------------
;- function: read_code
;- desciption: read a byte from internal code flash
;- parameters: 
;-     DPTR - address in valid CODE range
;- return value:
;-     ACC - data value
;-------------------------------------------------------------------------

read_code:
	ANL	DPCF, #~8h	; clear SIGEN (omit if SIGEN is never set)
	CLR	A
	MOVC	A, @A+DPTR
	RET

;--F----------------------------------------------------------------------
;- function: write_code
;- desciption: write a byte to internal code flash. Note that the CPU will
;-             idle for several milliseconds while the write completes. Also
;-             a page write of multiple bytes is preferred.
;- parameters: 
;-     DPTR - address in valid CODE range
;-     ACC  - data to write
;- return value:
;-     none
;-------------------------------------------------------------------------

write_code:
	ANL	DPCF, #~8h	; clear SIGEN (omit if SIGEN is never set)
	ANL	AUXR, #~2h	; clear EXTRAM (omit if EXTRAM is never set)
	ANL	MEMCON, #~20h	; clear LDPG (omit if LDPG is never set)
	ANL	MEMCON, #~8h	; clear DMEN (omit if DMEN is never set)
	ORL	MEMCON, #90h	; set MWEN and IAP
	MOVX	@DPTR, A
	ANL	MEMCON, #~90h	; clear MWEN and IAP
	RET

;--F----------------------------------------------------------------------
;- function: read_sig
;- desciption: read a byte from internal signature array
;- parameters: 
;-     DPTR - address in valid SIG range
;- return value:
;-     ACC - data value
;-------------------------------------------------------------------------

read_sig:
	ORL	DPCF, #8h	; set SIGEN
	CLR	A
	MOVC	A, @A+DPTR
	ANL	DPCF, #~8h	; clear SIGEN
	RET

;--F----------------------------------------------------------------------
;- function: write_sig
;- desciption: write a byte to internal signature array. Note that the CPU 
;-             will idle for several milliseconds while the write completes. 
;-             Also a page write of multiple bytes is preferred.
;- parameters: 
;-     DPTR - address in valid SIG range
;-     ACC  - data to write
;- return value:
;-     none
;-------------------------------------------------------------------------

write_sig:
	ANL	AUXR, #~2h	; clear EXTRAM (omit if EXTRAM is never set)
	ANL	MEMCON, #~20h	; clear LDPG (omit if LDPG is never set)
	ANL	MEMCON, #~8h	; clear DMEN (omit if DMEN is never set)
	ORL	DPCF, #8h	; set SIGEN
	ORL	MEMCON, #90h	; set MWEN and IAP
	MOVX	@DPTR, A
	ANL	DPCF, #~8h	; clear SIGEN
	ANL	MEMCON, #~90h	; clear MWEN and IAP
	RET

END

